package com.study.demo.aop.demo2;

import org.springframework.util.Assert;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @author: elvin
 * @time: 2019-05-23 14:29
 * @desc:
 **/
public abstract class ElvinOperation {
    private final String name;

    private final String key;

    private final String toString;

    /**
     * @since 4.3
     */
    protected ElvinOperation(ElvinOperation.Builder b) {
        this.name = b.name;
        this.key = b.key;
        this.toString = b.getOperationDescription().toString();
    }


    public String getName() {
        return this.name;
    }

    public String getKey() {
        return this.key;
    }


    /**
     * This implementation compares the {@code toString()} results.
     * @see #toString()
     */
    @Override
    public boolean equals(Object other) {
        return (other instanceof ElvinOperation && toString().equals(other.toString()));
    }

    /**
     * This implementation returns {@code toString()}'s hash code.
     * @see #toString()
     */
    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    /**
     * Return an identifying description for this cache operation.
     * <p>Returned value is produced by calling {@link ElvinOperation.Builder#getOperationDescription()}
     * during object construction. This method is used in {@link #hashCode} and
     * {@link #equals}.
     * @see ElvinOperation.Builder#getOperationDescription()
     */
    @Override
    public final String toString() {
        return this.toString;
    }


    /**
     * @since 4.3
     */
    public abstract static class Builder {

        private String name = "";

        private String key = "";

        public void setName(String name) {
            Assert.hasText(name, "Name must not be empty");
            this.name = name;
        }

        public void setElvinName(String cacheName) {
            Assert.hasText(cacheName, "Elvin name must not be empty");
        }

        public void setKey(String key) {
            Assert.notNull(key, "Key must not be null");
            this.key = key;
        }

        public String getKey() {
            return this.key;
        }

        /**
         * Return an identifying description for this caching operation.
         * <p>Available to subclasses, for inclusion in their {@code toString()} result.
         */
        protected StringBuilder getOperationDescription() {
            StringBuilder result = new StringBuilder(getClass().getSimpleName());
            result.append("[").append(this.name);
            result.append(" | key='").append(this.key).append("']");
            return result;
        }

        public abstract ElvinOperation build();
    }

}
